/*
 * File Name: P2PSender.java
 */
package co.edu.uniandes.intercon.server.networking;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import co.edu.uniandes.intercon.server.core.Constants;
import co.edu.uniandes.intercon.server.core.P2PException;
import co.edu.uniandes.intercon.server.util.ConnectionHelper;
import co.edu.uniandes.intercon.server.util.P2PLogger;

/**
 * Class to work as a message sender through <code>UDP</code>
 * 
 * @author Fabian Gutierrez [fagossa@gmail.com]
 */
public class UDPSender {
	private static DatagramSocket socket;
	private static boolean connected = false;

	static {
		try {
			socket = new DatagramSocket();
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Verify if there is an open <code>UDP</code> connection
	 * 
	 * @return <code>true</code> if an udp connetion is already done or
	 *         <code>false</code> otherwise
	 */
	public static boolean isConnected() {
		return socket != null && connected;
	}
	
	/**
	 * 
	 * @param newConnected
	 */
	public static void setConnected(boolean newConnected) {
		connected = newConnected;
	}

	/**
	 * Send the message specified
	 * 
	 * @param message
	 *            Serializable object to be sended
	 * @throws P2PException
	 *             When there was a problem sending the message throught
	 *             <code>UDP</code>
	 */
	public static void send(Serializable message) throws P2PException {
		ObjectOutputStream stream = null;
		ByteArrayOutputStream bytes = null;
		try {
			bytes = new ByteArrayOutputStream();
			stream = new ObjectOutputStream(bytes);
			stream.writeObject(message);
			byte[] array = bytes.toByteArray();
			DatagramPacket datagram = new DatagramPacket(array, array.length,
					InetAddress.getByName(Constants.MCAST_ADDR),
					Constants.DEST_PORT); // multicast
						
			socket.send(datagram);
		} catch (Exception e) {
			P2PLogger.logError("Error al enviar mensaje", e);
			throw new P2PException("Error comunicandose con el sistema remoto");
		} finally {
			ConnectionHelper.close(stream);
			ConnectionHelper.close(bytes);
		}
	}

	/**
	 * Release current open connection
	 */
	public static void release() {
		if (socket != null) {
			socket.close();
		}
		connected = false;
	}

}
